import { ArrayMap } from 'db://assets/core/struct/ArrayMap';
import { app } from '../app/App';
import { Protocol } from '../../proto/msg';
import { EventEnum, SceneEnum } from '../share/Enum';
import { SocketRespWrap } from '../../core/module/socket/BaseTypes';
import { Lobby } from '../../zbundleScript/lobby/Lobby';


export class GameModel {
    private _kindId: number = 0;
    get kindId() {
        return this._kindId;
    }

    /**
     * 玩家房间号
     */
    private _roomId: number = 0;

    public get roomId(): number {
        return this._roomId;
    }

    private _roomState: proto.RoomStateEnum = proto.RoomStateEnum.FREE;
    get roomState() {
        return this._roomState;
    }

   
    private _userInfos: ArrayMap<number, proto.RoomUserInfo> = new ArrayMap();
    get userInfos() {
        return this._userInfos;
    }
    /**
     * 更新房间信息
     * @param roomId 
     * @param kindId 
     */
    saveRoomInfo(roomId: number, kindId: number) {
        this._roomId = roomId;
        this._kindId = kindId;
    }

    /**
     * 更新玩家信息
     * @param userInfos 
     */
    updateRoomUserInfo(userInfos: proto.RoomUserInfo[]) {
        userInfos.forEach(userInfo => {
            this._userInfos.set(userInfo.userId, userInfo)
        })
    }

    /**
     * 移除玩家信息
     */
    removeUser(userId: number) {
        this._userInfos.delete(userId);
    }

    /**
     * 设置房间状态
     * @param state 
     */
    setRoomState(state: proto.RoomStateEnum) {
        this._roomState = state;
    }



    private _initServer(callback?) {
        app.net.connect(app.model.global.serverIp, app.model.global.gamePort, callback)
        this._registerPushMsg()
    }

    private _registerPushMsg() {
        app.net.offAllPushMsg(this)
        app.net.onPushMsg(this, Protocol.PUSH_ROOM_USER_UPDATE, this._onPushMsg.bind(this))
        app.net.onPushMsg(this, Protocol.PUSH_ROOM_USER_LEAVE, this._onPushMsg.bind(this))
        app.net.onPushMsg(this, Protocol.PUSH_ROOM_STATE, this._onPushMsg.bind(this))
    }


    private _onPushMsg(resp: SocketRespWrap) {
        switch (resp.cmd) {
            case Protocol.PUSH_ROOM_USER_UPDATE:
                {
                    const data = resp.body as proto.RoomUserInfos
                    this.updateRoomUserInfo(data.userInfos)
                    console.log('***********PUSH_ROOM_USER_UPDATE:', data)
                    app.event.emit(EventEnum.GameUpdate)
                }
                break
            case Protocol.PUSH_ROOM_USER_LEAVE:
                {
                    const data = resp.body as proto.User
                    this.removeUser(data.userId)
                    app.event.emit(EventEnum.GameUpdate)
                    if (data.userId == app.model.user.userId) {
                        app.model.login.silentLogin()
                    }
                }
                break
            case Protocol.PUSH_ROOM_STATE:
                {
                    const data = resp.body as proto.RoomState;
                    app.model.game.setRoomState(data.state)
                    app.event.emit(EventEnum.GameUpdate)
                }
                break
        }
    }

    enterRoomReq(userId: number, callback?) {
        this._initServer(() => {
            app.net.sendData(Protocol.GAME_USER_ENTER_ROOM, { userId }, callback)
        })
    }

    userReadReq(callback?) {
        app.net.sendData(Protocol.GAME_USER_READY, callback)
    }

    userLeaveReq(callback?) {
        app.net.sendData(Protocol.GAME_USER_LEAVE_ROOM, callback)
    }
}


